Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Diagnostics] Return rvalue reference from temporary argument #127400

Merged
merged 4 commits into from
Mar 13, 2025

Conversation

hahnjo
Copy link
Member

@hahnjo hahnjo commented Feb 16, 2025

This fixes compilation issues with GCC and C++23:

error: cannot bind non-const lvalue reference of type
'llvm::OptimizationRemarkMissed&' to an rvalue of type
'llvm::OptimizationRemarkMissed'

Closes #105778

@llvmbot
Copy link
Member

llvmbot commented Feb 16, 2025

@llvm/pr-subscribers-llvm-ir

Author: Jonas Hahnfeld (hahnjo)

Changes

This fixes compilation issues with GCC and C++23:

error: cannot bind non-const lvalue reference of type
'llvm::OptimizationRemarkMissed&' to an rvalue of type
'llvm::OptimizationRemarkMissed'

Closes #105778


Full diff: https://github.com/llvm/llvm-project/pull/127400.diff

3 Files Affected:

  • (modified) llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h (+5)
  • (modified) llvm/include/llvm/IR/DiagnosticInfo.h (+18-6)
  • (modified) llvm/lib/Analysis/InlineAdvisor.cpp (+7-1)
diff --git a/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h b/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h
index 7b14e55782adb..2640bb9194010 100644
--- a/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h
+++ b/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h
@@ -69,6 +69,11 @@ class OptimizationRemarkEmitter {
   /// Output the remark via the diagnostic handler and to the
   /// optimization record file.
   void emit(DiagnosticInfoOptimizationBase &OptDiag);
+  /// Also allow r-value for OptDiag to allow emitting a temporarily-constructed
+  /// diagnostic.
+  void emit(DiagnosticInfoOptimizationBase &&OptDiag) {
+    emit(static_cast<DiagnosticInfoOptimizationBase &>(OptDiag));
+  }
 
   /// Take a lambda that returns a remark which will be emitted.  Second
   /// argument is only used to restrict this to functions.
diff --git a/llvm/include/llvm/IR/DiagnosticInfo.h b/llvm/include/llvm/IR/DiagnosticInfo.h
index 694785317af04..1e26cfdd17b5f 100644
--- a/llvm/include/llvm/IR/DiagnosticInfo.h
+++ b/llvm/include/llvm/IR/DiagnosticInfo.h
@@ -30,6 +30,7 @@
 #include <iterator>
 #include <optional>
 #include <string>
+#include <utility>
 
 namespace llvm {
 
@@ -625,14 +626,14 @@ operator<<(RemarkT &R,
 /// Also allow r-value for the remark to allow insertion into a
 /// temporarily-constructed remark.
 template <class RemarkT>
-RemarkT &
+RemarkT &&
 operator<<(RemarkT &&R,
            std::enable_if_t<
                std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
                StringRef>
                S) {
   R.insert(S);
-  return R;
+  return std::move(R);
 }
 
 template <class RemarkT>
@@ -647,14 +648,14 @@ operator<<(RemarkT &R,
 }
 
 template <class RemarkT>
-RemarkT &
+RemarkT &&
 operator<<(RemarkT &&R,
            std::enable_if_t<
                std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
                DiagnosticInfoOptimizationBase::Argument>
                A) {
   R.insert(A);
-  return R;
+  return std::move(R);
 }
 
 template <class RemarkT>
@@ -669,14 +670,14 @@ operator<<(RemarkT &R,
 }
 
 template <class RemarkT>
-RemarkT &
+RemarkT &&
 operator<<(RemarkT &&R,
            std::enable_if_t<
                std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
                DiagnosticInfoOptimizationBase::setIsVerbose>
                V) {
   R.insert(V);
-  return R;
+  return std::move(R);
 }
 
 template <class RemarkT>
@@ -690,6 +691,17 @@ operator<<(RemarkT &R,
   return R;
 }
 
+template <class RemarkT>
+RemarkT &&
+operator<<(RemarkT &&R,
+           std::enable_if_t<
+               std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
+               DiagnosticInfoOptimizationBase::setExtraArgs>
+               EA) {
+  R.insert(EA);
+  return std::move(R);
+}
+
 /// Common features for diagnostics dealing with optimization remarks
 /// that are used by IR passes.
 class DiagnosticInfoIROptimization : public DiagnosticInfoOptimizationBase {
diff --git a/llvm/lib/Analysis/InlineAdvisor.cpp b/llvm/lib/Analysis/InlineAdvisor.cpp
index 12553dd446a61..2041610cd5ee9 100644
--- a/llvm/lib/Analysis/InlineAdvisor.cpp
+++ b/llvm/lib/Analysis/InlineAdvisor.cpp
@@ -338,7 +338,7 @@ static raw_ostream &operator<<(raw_ostream &R, const ore::NV &Arg) {
 }
 
 template <class RemarkT>
-RemarkT &operator<<(RemarkT &&R, const InlineCost &IC) {
+RemarkT &operator<<(RemarkT &R, const InlineCost &IC) {
   using namespace ore;
   if (IC.isAlways()) {
     R << "(cost=always)";
@@ -352,6 +352,12 @@ RemarkT &operator<<(RemarkT &&R, const InlineCost &IC) {
     R << ": " << ore::NV("Reason", Reason);
   return R;
 }
+
+template <class RemarkT>
+RemarkT &&operator<<(RemarkT &&R, const InlineCost &IC) {
+  static_cast<RemarkT &>(R) << IC;
+  return std::move(R);
+}
 } // namespace llvm
 
 std::string llvm::inlineCostStr(const InlineCost &IC) {

@llvmbot
Copy link
Member

llvmbot commented Feb 16, 2025

@llvm/pr-subscribers-llvm-analysis

Author: Jonas Hahnfeld (hahnjo)

Changes

This fixes compilation issues with GCC and C++23:

error: cannot bind non-const lvalue reference of type
'llvm::OptimizationRemarkMissed&amp;' to an rvalue of type
'llvm::OptimizationRemarkMissed'

Closes #105778


Full diff: https://github.com/llvm/llvm-project/pull/127400.diff

3 Files Affected:

  • (modified) llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h (+5)
  • (modified) llvm/include/llvm/IR/DiagnosticInfo.h (+18-6)
  • (modified) llvm/lib/Analysis/InlineAdvisor.cpp (+7-1)
diff --git a/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h b/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h
index 7b14e55782adb..2640bb9194010 100644
--- a/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h
+++ b/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h
@@ -69,6 +69,11 @@ class OptimizationRemarkEmitter {
   /// Output the remark via the diagnostic handler and to the
   /// optimization record file.
   void emit(DiagnosticInfoOptimizationBase &OptDiag);
+  /// Also allow r-value for OptDiag to allow emitting a temporarily-constructed
+  /// diagnostic.
+  void emit(DiagnosticInfoOptimizationBase &&OptDiag) {
+    emit(static_cast<DiagnosticInfoOptimizationBase &>(OptDiag));
+  }
 
   /// Take a lambda that returns a remark which will be emitted.  Second
   /// argument is only used to restrict this to functions.
diff --git a/llvm/include/llvm/IR/DiagnosticInfo.h b/llvm/include/llvm/IR/DiagnosticInfo.h
index 694785317af04..1e26cfdd17b5f 100644
--- a/llvm/include/llvm/IR/DiagnosticInfo.h
+++ b/llvm/include/llvm/IR/DiagnosticInfo.h
@@ -30,6 +30,7 @@
 #include <iterator>
 #include <optional>
 #include <string>
+#include <utility>
 
 namespace llvm {
 
@@ -625,14 +626,14 @@ operator<<(RemarkT &R,
 /// Also allow r-value for the remark to allow insertion into a
 /// temporarily-constructed remark.
 template <class RemarkT>
-RemarkT &
+RemarkT &&
 operator<<(RemarkT &&R,
            std::enable_if_t<
                std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
                StringRef>
                S) {
   R.insert(S);
-  return R;
+  return std::move(R);
 }
 
 template <class RemarkT>
@@ -647,14 +648,14 @@ operator<<(RemarkT &R,
 }
 
 template <class RemarkT>
-RemarkT &
+RemarkT &&
 operator<<(RemarkT &&R,
            std::enable_if_t<
                std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
                DiagnosticInfoOptimizationBase::Argument>
                A) {
   R.insert(A);
-  return R;
+  return std::move(R);
 }
 
 template <class RemarkT>
@@ -669,14 +670,14 @@ operator<<(RemarkT &R,
 }
 
 template <class RemarkT>
-RemarkT &
+RemarkT &&
 operator<<(RemarkT &&R,
            std::enable_if_t<
                std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
                DiagnosticInfoOptimizationBase::setIsVerbose>
                V) {
   R.insert(V);
-  return R;
+  return std::move(R);
 }
 
 template <class RemarkT>
@@ -690,6 +691,17 @@ operator<<(RemarkT &R,
   return R;
 }
 
+template <class RemarkT>
+RemarkT &&
+operator<<(RemarkT &&R,
+           std::enable_if_t<
+               std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
+               DiagnosticInfoOptimizationBase::setExtraArgs>
+               EA) {
+  R.insert(EA);
+  return std::move(R);
+}
+
 /// Common features for diagnostics dealing with optimization remarks
 /// that are used by IR passes.
 class DiagnosticInfoIROptimization : public DiagnosticInfoOptimizationBase {
diff --git a/llvm/lib/Analysis/InlineAdvisor.cpp b/llvm/lib/Analysis/InlineAdvisor.cpp
index 12553dd446a61..2041610cd5ee9 100644
--- a/llvm/lib/Analysis/InlineAdvisor.cpp
+++ b/llvm/lib/Analysis/InlineAdvisor.cpp
@@ -338,7 +338,7 @@ static raw_ostream &operator<<(raw_ostream &R, const ore::NV &Arg) {
 }
 
 template <class RemarkT>
-RemarkT &operator<<(RemarkT &&R, const InlineCost &IC) {
+RemarkT &operator<<(RemarkT &R, const InlineCost &IC) {
   using namespace ore;
   if (IC.isAlways()) {
     R << "(cost=always)";
@@ -352,6 +352,12 @@ RemarkT &operator<<(RemarkT &&R, const InlineCost &IC) {
     R << ": " << ore::NV("Reason", Reason);
   return R;
 }
+
+template <class RemarkT>
+RemarkT &&operator<<(RemarkT &&R, const InlineCost &IC) {
+  static_cast<RemarkT &>(R) << IC;
+  return std::move(R);
+}
 } // namespace llvm
 
 std::string llvm::inlineCostStr(const InlineCost &IC) {

Copy link

github-actions bot commented Feb 16, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

This fixes compilation issues with GCC and C++23:
```
error: cannot bind non-const lvalue reference of type
'llvm::OptimizationRemarkMissed&' to an rvalue of type
'llvm::OptimizationRemarkMissed'
```

Closes llvm#105778
@hahnjo hahnjo requested a review from vitalybuka February 25, 2025 09:59
@vitalybuka vitalybuka removed their request for review February 27, 2025 05:30
@hahnjo hahnjo requested a review from nikic March 10, 2025 16:50
@nikic nikic requested review from kuhar and dwblaikie March 10, 2025 16:57
@nikic nikic changed the title Return rvalue reference from temporary argument [Diagnostics] Return rvalue reference from temporary argument Mar 10, 2025
Copy link
Collaborator

@dwblaikie dwblaikie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like OK changes.

I wouldn't mind a unit test for something low level/broadly used like this, but wouldn't insist on it.

@hahnjo
Copy link
Member Author

hahnjo commented Mar 11, 2025

I wouldn't mind a unit test for something low level/broadly used like this, but wouldn't insist on it.

I generally agree, but unfortunately there is none for OptimizationRemarkEmitter and I'm not really familiar with the code (just trying to address compilation errors when experimenting with C++23) 😧

@kuhar kuhar requested a review from zero9178 March 11, 2025 21:36
@hahnjo hahnjo requested a review from kuhar March 12, 2025 18:38
Copy link
Member

@kuhar kuhar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM % nit

@arsenm arsenm merged commit 44ff94e into llvm:main Mar 13, 2025
9 of 10 checks passed
@hahnjo hahnjo deleted the diagnostic-rvalue branch March 13, 2025 07:21
@hahnjo
Copy link
Member Author

hahnjo commented Mar 13, 2025

@arsenm thanks for merging. However, for future changes I would prefer to do this myself, both to decide on the author email address (work or private; this merge got it right because I contributed privately outside of work hours) and to make sure I'm available to respond to any issues reported by the bots...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[IR]: Bug - dangling reference
6 participants